02.2 精通自定义 View 之视图动画——视图动画的代码实现

返回自定义 View 目录

2.2.1 概述

使用 XML 来添加动画可以很大限度地提高代码复用性,但有时只需要临时使用一个动画,就没有必要单独写一个 XML 动画文件了,可以使用代码的方法生成一个动画操作。

标签
scale ScaleAnimation
alpha AlphaAnimation
rotate RotateAnimation
translate TranslateAnimation
set AnimationSet

Animation 类中共用的属性方法:

标签属性 方 法 说明
android:duration setDuration(long) 动画的运行时间 (以毫秒为单位);必须设置
android:fillAfter setFillAfter(boolean) 动画结束时是否保持动画最后的状态;默认为 false,优先于 fillBefore。
android:fillBefore setFillBefore(boolean) 动画结束时是否还原到开始动画前的状态;默认为 true。
android:fillEnabled setFillEnabled(boolean) 是否应用 fillBefore 的值,对 fillAfter 无影响;默认为true。
android:repeatCount setRepeatCount(int) 重复次数,取值为整数或 Animation.INFINITE。
android:repeatMode setRepeatMode(int) 重复类型有两个值,reverse 表示倒序回放,restart 表示从头播放
android:interpolator setInterpolator(Interpolator) 设定插值器(指定的动画效果,譬如回弹等)
android:detachWallpaper setDetachWallpaper(boolean)
android:startOffset setStartOffset(long) 调用 start 函数之后等待开始运行的时间,单位为毫秒
android:zAdjustment setZAdjustment(int) 表示被设置动画的内容运行时在 Z 轴上的位置(top / bottom / normal),默认为 normal。

2.2.2 ScaleAnimation

1
2
3
4
5
6
ScaleAnimation(float fromX, float toX, float fromY, float toY)
ScaleAnimation(float fromX, float toX, float fromY, float toY,
float pivotX, float pivotY)
ScaleAnimation(float fromX, float toX, float fromY, float toY,
int pivotXType, float pivotXValue,
int pivotYType, float pivotYValue)

pivotXType 取值为:
Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT。

示例:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0.0"
android:toXScale="1.4"
android:fromYScale="0.0"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:duration="700"/>

对应代码:

1
2
3
4
5
ScaleAnimation scaleAnim = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnim.setDuration(700);
tv.startAnimation(scaleAnim);

2.2.3 AlphaAnimation

1
AlphaAnimation(float fromAlpha, float toAlpha)

示例:

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:fillBefore="true"
android:duration="3000"/>

对应代码:

1
2
3
AlphaAnimation alphaAnim = new AlphaAnimation(1.0f, 0.1f);
alphaAnim.setDuration(3000);
alphaAnim.setFillBefore(true);

2.2.4 RotateAnimation

1
2
3
4
5
RotateAnimation(float fromDegrees, float toDegrees)
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
RotateAnimation(float fromDegrees, float toDegrees,
int pivotXType, float pivotXValue,
int pivotYType, float pivotYValue)

pivotXType 取值为:
Animation.ABSOLUTE、Animation.RELATIVE_TO_SELF、Animation.RELATIVE_TO_PARENT

示例:

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="-650"
android:pivotX="50%"
android:pivotY="50%"
android:duration="3000"
android:fillAfter="true"/>

对应代码:

1
2
3
4
5
RotateAnimation alphaAnim = new RotateAnimation(0, -650,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
alphaAnim.setDuration(3000);
alphaAnim.setFillAfter(true);

2.2.5 TranslateAnimation

1
2
3
4
5
6
TranslateAnimation(float fromXDelta, float toXDelta,
float fromYDelta, float toYDelta)
TranslateAnimation(int fromXType, float fromXValue,
int toXType, float toXValue,
int fromYType, float fromYValue,
int toYType, float toYValue)

示例:

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="-80"
android:fromYDelta="0"
android:toYDelta="-80"
android:duration="2000"
android:fillBefore="true"/>

对应代码:

1
2
3
4
5
TranslateAnimation alphaAnim = new TranslateAnimation(
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -80,
Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -80);
alphaAnim.setDuration(2000);
alphaAnim.setFillBefore(true);

2.2.6 AnimationSet

1
AnimationSet(boolean shareInterpolator)

shareInterpolator 参数取值为 true 时,用于 AnimationSet 类中定义一个插值器,其下面的所有动画共用该插值器;取值为 false,则表示其下面的动画定义各自的插值器。增加动画的函数:

1
public void addAnimation(Animation a)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fillAfter="true">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"/>
<scale
android:fromXScale="0.0"
android:toXScale="1.4"
android:fromYScale="0.0"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%" />
<rotate
android:fromDegrees="0"
android:toDegrees="720"
android:pivotX="50%"
android:pivotY="50%"/>
</set>

对应代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Animation alphaAnim = new AlphaAnimation(0, 1.0f);
Animation scaleAnim = new ScaleAnimation(0, 1.4f, 0, 1.4f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
Animation rotateAnim = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
AnimationSet setAnim = new AnimationSet(true);
setAnim.addAnimation(alphaAnim);
setAnim.addAnimation(scaleAnim);
setAnim.addAnimation(rotateAnim);
setAnim.setDuration(3000);
setAnim.setFillAfter(true);
view.startAnimation(setAnim);

2.2.7 Animation

Animation 还有一些比较实用的方法介绍,如下:

方法 说明
cancel() 取消动画
reset() 将控件重置到动画开始前状态
hasStarted() 判断当前 Animation 是否开始
hasEnded() 判断当前 Animation 是否结束
setAnimationListener() 设置动画监听

Animation.AnimationListener:

1
2
3
4
5
6
7
8
public static interface AnimationListener {
// 动画开始时调用
void onAnimationStart(Animation animation);
// 动画结束时调用
void onAnimationEnd(Animation animation);
// 动画重复时调用
void onAnimationRepeat(Animation animation);
}

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
final RotateAnimation rotateAnim = new RotateAnimation(0, 720,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnim.setDuration(2000);
rotateAnim.setFillAfter(true);
ScaleAnimation scaleAnim = new ScaleAnimation(0, 1.4f, 0, 1.4f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnim.setDuration(700);
scaleAnim.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
view.startAnimation(rotateAnim);
}
@Override
public void onAnimationRepeat(Animation animation) { }
});
view.startAnimation(scaleAnim);